package com.eunion.core.common.jpa.query;

import java.util.Arrays;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.util.ObjectUtils;

import com.eunion.core.common.jpa.MatchType;

public final class QuickFilterQueryRequirement<Entity, Bean> implements QueryRequirement<Entity, Bean> {

    private static final long serialVersionUID = 1L;

    private final String quickFilter;

    private final String[] columns;

    private final MatchType matchType;

    public QuickFilterQueryRequirement(String quickFilter, String... columns) {
        this(quickFilter, MatchType.CONTAINS, columns);
    }

    public QuickFilterQueryRequirement(String quickFilter, MatchType matchType, String... columns) {
        this.quickFilter = quickFilter;
        this.columns = columns;
        this.matchType = matchType;
    }

    @Override
    public Predicate where(Root<Entity> root, CriteriaQuery<Bean> query, CriteriaBuilder cb) {
        if (ObjectUtils.isEmpty(quickFilter)) {
            return null;
        }
        return cb.or(Arrays.stream(columns)
                .map(e -> matchType == MatchType.EQUAL ? cb.equal(root.get(e), query()) : cb.like(root.get(e), query()))
                .toArray(Predicate[]::new));
    }

    private String query() {
        switch (matchType) {
        case CONTAINS:
            return "%" + quickFilter + "%";
        case END_WITH:
            return quickFilter + "%";
        case EQUAL:
            return quickFilter;
        case START_WITH:
            return "%" + quickFilter;
        default:
            throw new UnsupportedOperationException(matchType.name());
        }
    }

}
